//
//  NetworkCenter.swift
//  Inquiry
//
//  Created by SSD on 2019/9/10.
//  Copyright © 2019 SSD. All rights reserved.
//

import Foundation
class NetworkCenter {}
extension NetworkCenter {
    static func options(_ component: String, _ params: ParameterDictionary?, _ afterUrlHeaders:ParameterDictionary? = nil, _ headers: [String : String]? = nil, functionName: String = #function) -> SWNetworkRequest {
        let url = packFullUrl(with: component, isToUpload: false)
        let parameters = packParameter(with: params)
        let api = ApiCenter(method: .options, url: url, parameters: parameters, functionName: functionName)
        let request = SWNetworkRequest(api: api)
        request.headers = headers
        return request
    }
    static func get(_ component: String, _ params: ParameterDictionary?, _ headers: [String : String]? = nil, functionName: String = #function) -> SWNetworkRequest {
        let url = packFullUrl(with: component, isToUpload: false)
        let parameters = packParameter(with: params)
        let api = ApiCenter(method: SWNetwork.HttpMethod.get, url: url, parameters: parameters, functionName: functionName)
        let request = SWNetworkRequest(api: api)
        request.headers = headers
        return request
    }
    static func head(_ component: String, _ params: ParameterDictionary?, _ afterUrlHeaders:ParameterDictionary? = nil, _ headers: [String : String]? = nil, functionName: String = #function) -> SWNetworkRequest {
        let url = packFullUrl(with: component, isToUpload: false)
        let parameters = packParameter(with: params)
        let api = ApiCenter(method: .head, url: url, parameters: parameters, functionName: functionName)
        let request = SWNetworkRequest(api: api)
        request.headers = headers
        return request
    }
    static func post(_ component: String, _ params: ParameterDictionary?, _ afterUrlHeaders:ParameterDictionary? = nil, _ headers: [String : String]? = nil, functionName: String = #function) -> SWNetworkRequest {
        let url = packFullUrl(with: component, isToUpload: false)
        let parameters = packParameter(with: params)
        let api = ApiCenter(method: .post, url: url, parameters: parameters, functionName: functionName)
        let request = SWNetworkRequest(api: api)
        request.headers = headers
        return request
    }
    static func put(_ component: String, _ params: ParameterDictionary?, _ afterUrlHeaders:ParameterDictionary?, _ headers: [String : String]? = nil, functionName: String = #function) -> SWNetworkRequest {
        let url = packFullUrl(with: component, isToUpload: false)
        let parameters = packParameter(with: params)
        let api = ApiCenter(method: .put, url: url, parameters: parameters, functionName: functionName)
        let request = SWNetworkRequest(api: api)
        request.headers = headers
        return request
    }
    static func patch(_ component: String, _ params: ParameterDictionary?, _ afterUrlHeaders:ParameterDictionary?, _ headers: [String : String]? = nil, functionName: String = #function) -> SWNetworkRequest {
        let url = packFullUrl(with: component, isToUpload: false)
        let parameters = packParameter(with: params)
        let api = ApiCenter(method: .patch, url: url, parameters: parameters, functionName: functionName)
        let request = SWNetworkRequest(api: api)
        request.headers = headers
        return request
    }
    static func delete(_ component: String, _ params: ParameterDictionary?, _ afterUrlHeaders:ParameterDictionary?, _ headers: [String : String]? = nil, functionName: String = #function) -> SWNetworkRequest {
        let url = packFullUrl(with: component, isToUpload: false)
        let parameters = packParameter(with: params)
        let api = ApiCenter(method: .delete, url: url, parameters: parameters, functionName: functionName)
        let request = SWNetworkRequest(api: api)
        request.headers = headers
        return request
    }
    
    static func trace(_ component: String, _ params: ParameterDictionary?, _ afterUrlHeaders:ParameterDictionary?, _ headers: [String : String]? = nil, functionName: String = #function) -> SWNetworkRequest {
        let url = packFullUrl(with: component, isToUpload: true)
        let parameters = packParameter(with: params)
        let api = ApiCenter(method: .trace, url: url, parameters: parameters, functionName: functionName)
        let request = SWNetworkRequest(api: api)
        request.headers = headers
        return request
    }
    static func connect(_ component: String, _ params: ParameterDictionary?, _ afterUrlHeaders:ParameterDictionary?, _ headers: [String : String]? = nil, functionName: String = #function) -> SWNetworkRequest {
        let url = packFullUrl(with: component, isToUpload: true)
        let parameters = packParameter(with: params)
        let api = ApiCenter(method: .connect, url: url, parameters: parameters, functionName: functionName)
        let request = SWNetworkRequest(api: api)
        request.headers = headers
        return request
    }
}
private extension NetworkCenter {
    static func packFullUrl(with component: String, isToUpload: Bool = false) -> String {
        var fullUrl = NetworkConfig.WEB_PROTOCOL + NetworkConfig.HOST + ((NetworkConfig.PORT != nil) ? "\(NetworkConfig.PORT!)" : "") + (isToUpload ? NetworkConfig.PATH_FOR_UPLOADING_FILE : NetworkConfig.PATH) + component
        if isToUpload, let uploadFullUrl = fullUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
            fullUrl = uploadFullUrl
        }
        return fullUrl
    }
    static func packParameter(with dict: ParameterDictionary?) -> [String:Any] {
        let allParams = dict ?? ParameterDictionary()
        return allParams.toStandardDictionary()
    }
}
extension NetworkCenter {
    static func responseSuccess(_ anyObject: Any?, _ response: SWNetworkResponse) -> SWNetworkResponse {
        if let dictObject = anyObject as? [String:Any] {
            response.data = dictObject
            if let code = dictObject.int(for: "code") {
                response.code = code
            }
            response.message = dictObject.string(for: "message")
        } else if let arrayObject = anyObject as? [Any] {
            response.data = ["items" : arrayObject]
        } else if let anyObject = anyObject {
            response.data = ["data" : anyObject]
        }
        return response
    }
}
